﻿using System;
using System.Collections.Generic;

namespace Shell.Common
{
    public static class EnumerableUtils
    {
        public static IEnumerable<T> Yield<T>(this T value)
        {
            yield return value;
        }

        public static TType SelectMin<TType, TValue>(this IEnumerable<TType> source, Func<TType, TValue> selector)
                        where TValue : struct, IComparable<TValue>
        {
            return SelectCompare(source, selector, (a, b) => a.CompareTo(b) < 0);
        }

        public static TType SelectMax<TType, TValue>(this IEnumerable<TType> source, Func<TType, TValue> selector)
                        where TValue : struct, IComparable<TValue>
        {
            return SelectCompare(source, selector, (a, b) => a.CompareTo(b) > 0);
        }

        public static TType SelectCompare<TType, TValue>(this IEnumerable<TType> source, Func<TType, TValue> selector, Func<TValue, TValue, bool> compare)
            where TValue : struct
        {
            var result = default(TType);
            TValue? value = null;

            foreach (var v in source)
            {
                var newValue = selector(v);

                if (value == null || compare(newValue,(TValue) value))
                {
                    value = newValue;
                    result = v;
                }
            }
            return result;
        }

        public static void Add<T>(this IList<T> list, IEnumerable<T> values)
        {
            foreach (var value in values)
            {
                list.Add(value);
            }
        }

        public static void PushRange<T>(this Stack<T> stack, IEnumerable<T> range)
        {
            foreach (var value in range)
            {
                stack.Push(value);
            }
        }
    }
}
